﻿using GN.Pay.TradeChannel.DefaultImpl;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GN.Pay.TradeChannel.AliPay.Response
{
    /// <summary>
    /// 退款通知响应实体
    /// </summary>
    [Serializable]
    class RefundNotifyResponseEntity : NotifyResponseEntity
    {
        /// <summary>
        /// 退款批次号，原请求退款批次号。 
        /// </summary>
        public string Batch_no { get; set; }

        /// <summary>
        /// 退款成功 总数
        /// </summary>
        public int Success_Num { get; set; }

        /// <summary>
        /// 处理结果详情 
        /// </summary>
        public string Result_Details { get; set; }

        /// <summary>
        /// 解冻结果明细
        /// </summary>
        public string Unfreezed_Details { get; set; }

        /// <summary>
        /// 获取是否成功
        /// </summary>
        /// <returns></returns>
        public bool IsSuccess()
        {
            return !string.IsNullOrWhiteSpace(this.Result_Details);
        }

        /// <summary>
        /// 退款结果
        /// </summary>
        /// <param name="channel"></param>
        /// <returns></returns>
        public List<ITradeRefundApplyResult> ToRefundResults(IChannel channel)
        {
            if (string.IsNullOrWhiteSpace(this.Batch_no))
            {
                channel.ThrowChannelValidationException("支付宝交易退款通知的批号 Batch_no 号为null或空白。");
            }
            if (string.IsNullOrWhiteSpace(this.Result_Details))
            {
                channel.ThrowChannelValidationException("支付宝交易退款通知的结果详情 Result_Details 号为null或空白。");
            }
            List<ITradeRefundApplyResult> items = new List<ITradeRefundApplyResult>();
            //第一笔交易#第二笔交易#第三笔交易...#第N笔交易
            string[] strResults = this.Result_Details.Split(new char[] { '#' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (string detailResult in strResults)
            {
                items.Add(this.CreateDetailResult(detailResult, channel));
            }
            return items;
        }

        private string RefundResultErrorMessage(string detailResult)
        {
            return "支付宝交易退款通知响应 result_details 的格式不正确:" + detailResult;
        }

        /// <summary>
        /// 创建详情结果
        /// </summary>
        /// <param name="detailResult"></param>
        /// <param name="channel"></param>
        /// <returns></returns>
        private ITradeRefundApplyResult CreateDetailResult(string detailResult, IChannel channel)
        {          
            //交易退款数据集$收费退款数据集|分润退款数据集|分润退款数据集|...|分润退款数据集$$退子交易
            var tradeResultSet = detailResult.Split(new char[] { '#' }, StringSplitOptions.RemoveEmptyEntries);
            if (tradeResultSet.Length < 1)
            {
                channel.ThrowChannelValidationException(RefundResultErrorMessage(detailResult));
            }
            tradeResultSet = tradeResultSet[0].Split(new string[] { "$$" }, StringSplitOptions.RemoveEmptyEntries);
            if (tradeResultSet.Length < 1)
            {
                channel.ThrowChannelValidationException(RefundResultErrorMessage(detailResult));
            }
            tradeResultSet = tradeResultSet[0].Split(new char[] { '$' }, StringSplitOptions.RemoveEmptyEntries);
            if (tradeResultSet.Length < 1)
            {
                channel.ThrowChannelValidationException(RefundResultErrorMessage(detailResult));
            }
            //：原付款支付宝交易号^退款总金额^处理结果码。 
            var tradeResults = tradeResultSet[0].Split(new char[] { '^' }, StringSplitOptions.RemoveEmptyEntries);
            if (tradeResults.Length < 3)
            {
                channel.ThrowChannelValidationException(RefundResultErrorMessage(detailResult));
            }
            string tradeNo = tradeResults[0];
            decimal refundMoney = Convert.ToDecimal(tradeResults[1]);
            string state = tradeResults[2];
            if (state.Equals("SUCCESS", StringComparison.InvariantCultureIgnoreCase))
            {
                return new TradeRefundApplyResult(channel, this.Batch_no, tradeNo, refundMoney, 0m, null, TradeApplyResultState.Complete_Success, "退款成功");
            }
            return new TradeRefundApplyResult(channel, this.Batch_no, tradeNo, refundMoney, 0m, null, TradeApplyResultState.Apply_Error, state);
        }
    }
}
